package com.multi.publicly.service.impl;

import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.multi.common.constant.CacheConstants;
import com.multi.common.constant.SourceConstant;
import com.multi.common.core.domain.entity.BkTenantInfo;
import com.multi.common.core.redis.RedisCache;
import com.multi.common.exception.base.BaseException;
import com.multi.common.utils.SecurityUtils;
import com.multi.common.utils.StringUtils;
import com.multi.publicly.domain.WxUserInfo;
import com.multi.publicly.service.PublicService;
import com.multi.publicly.service.WxUserInfoService;
import com.multi.publicly.utils.WxMiddleUtils;
import com.multi.publicly.vo.LoginFormVo;
import com.multi.tenant.service.IBkTenantInfoService;
import com.multi.tenant.util.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.token.TokenService;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description 公共接口处理实现类
 * @ClassName PublicServiceImpl
 * @Author pzj
 * @Data 2024/12/2 10:43
 */
@Slf4j
@Service
public class PublicServiceImpl implements PublicService {

    @Autowired
    private IBkTenantInfoService bkTenantInfoService;

    @Autowired
    private WxMiddleUtils wxMiddleUtils;

    @Autowired
    private WxUserInfoService wxUserInfoService;

    @Autowired
    private TokenUtils tokenUtils;

    @Autowired
    private RedisCache redisCache;

    @Override
    public String getPhone(String code, Long tenantId) {
        //根据Id获取租户信息
        BkTenantInfo bkTenantInfo = bkTenantInfoService.selectBkTenantInfoById(tenantId);
        //根据AppId和AppSecret获取token
        String access_token = wxMiddleUtils.obtainAccessToken(bkTenantInfo);
        //通过token获取用户的手机号
        String phone = wxMiddleUtils.obtainPhone(access_token, code);
        return phone;
    }

    @Override
    @DSTransactional
    public HashMap<String, Object> login(LoginFormVo loginFormVo) {
        String openId = wxMiddleUtils.obtainOpenId(loginFormVo);
        if (StringUtils.isBlank(openId)) {
            throw new BaseException("openid解析失败");
        }
        //查询openID信息
        WxUserInfo wxUserInfo = wxUserInfoService.selectByOpenId(openId);
        //如果用户获取为空，则新增用户
        if (wxUserInfo == null) {
            wxUserInfo = new WxUserInfo().setOpenId(openId)
                    .setUserPhone(loginFormVo.getPhone());
            //将用户信息进行存储
            wxUserInfoService.insertWxUserInfo(wxUserInfo);
        }
        //根据用户ID和租户ID生成对应的token信息
        Map<String, Object> claims = new HashMap<>();
        claims.put(SourceConstant.USER_ID, wxUserInfo.getId());
        claims.put(SourceConstant.TENANT_ID, loginFormVo.getTenantId());
        String token = tokenUtils.createToken(claims);
        //设置返回数据信息
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("token", token);
        hashMap.put("userId", wxUserInfo.getId());
        //这里将用户基本信息存储到redis中（七天）
        redisCache.setCacheObject(CacheConstants.WX_USER_INFO + wxUserInfo.getId(),
                wxUserInfo, 7, TimeUnit.DAYS);
        return hashMap;
    }

    @Override
    public WxUserInfo getInfo() {
        Long userId = SecurityUtils.getWxUserId();
        //根据userId查询用户信息
        WxUserInfo wxUserInfo = wxUserInfoService.selectByUserId(userId);
        return wxUserInfo;
    }
}
